#ifndef BIT_WIN_GENERIC_BITWISE_TEMPLATES
#define BIT_WIN_GENERIC_BITWISE_TEMPLATES


#include <algorithm>
#include <climits>

#include <QString>

#include "generic_bitwise.h"


namespace BitWin
{


//---- Concreete classes for bitwise-representable data


// Conventional integral data template class
template <typename T>
class IntegralBitwise: public GenericBitwise
{
    const T _value;

    explicit IntegralBitwise(const T value_);

    friend PGenericBitwise GenericBitwise::fromIntegral<T>(const T);

public:

    virtual QString bitwise() const;
    virtual QString hex() const;
    virtual QString dec() const;
};


template <typename T>
IntegralBitwise<T>::IntegralBitwise(const T value_):
    _value(value_)
{}

template <typename T>
QString IntegralBitwise<T>::bitwise() const
{
    QString result =
        QString::number(_value, 2)
            .rightJustified(sizeof(T) * CHAR_BIT, '0')
    ;
    std::reverse(result.begin(), result.end());
    return result;
}

template <typename T>
QString IntegralBitwise<T>::hex() const
{
    return QString("0x%1").arg(QString::number(_value, 16));
}

template <typename T>
QString IntegralBitwise<T>::dec() const
{
    return QString::number(_value, 10);
}


//---- Factories for bitwise-representable data concreete classes

template <typename T>
PGenericBitwise GenericBitwise::fromIntegral(const T value)
{
    return PGenericBitwise(new IntegralBitwise<T>(value));
}


template <typename T>
class GenericBitwise::FromIntegral
{
public:
    PGenericBitwise operator()(const T value) const
    {
        return GenericBitwise::fromIntegral<T>(value);
    }
};


template <typename T>
class GenericBitwise::FromSequence
{
public:
    PGenericBitwise operator()(const T& value) const
    {
        return GenericBitwise::fromSequence<T>(value);
    }
};

} // BitWin namespace end


#endif
